Статья про то, почему нужны import maps и как они работают.
На момент введение ES-модулей сообщество уже привыкло использовать пакеты из npm. При этом мы хотим писать код в браузере также, как пишем его обычно. И тут то и кроется конфликт.
Например, вы хотите импортировать библиотеку import lib from 'lib' - это то, как мы обычно делаем с npm. Однако в браузере нам бы необходимо было написать что-то вроде import lib from 'https://some.cdn.com/lib@1.0.0'.
Вот этот конфликт и решаются Import Maps. Они позволяют писать импорты в браузере также, как при использовании npm.
Например, на нашем примере это будет выглядеть так
<script type="importmap">
{
"lib": "https://some.cdn.com/lib@1.0.0"
}
</script>
<script type="module">
import lib from 'lib';
</script>
При этом скрипт с Import Map должен быть вставлен до первого скрипта с type=module. Также, вместо того, чтобы описывать объект с мапингом прямо в тэге script, можно подтягивать Import Map через src, но при этом заголовок Content-Type должен быть выставлен в application/importmap+json
<script type="importmap" src="/importamap.json"></script>
Кроме того у Import Maps есть несколько фишек
Во первых, можно делать Import Map на группу пакетов. Например, на lodash
<script type="importmap">
{
"imports": {
"lodash/": "/node_modules/lodash-es/"
}
}
</script>
<script type="module">
import toUpper from 'lodash/toUpper.js';
import toLower from 'lodash/toLower.js';
</script>
Во вторых, можно сделать алиасы на разные версии одного пакета
<script type="importmap">
{
"imports": {
"lodash@3/": "https://unpkg.com/lodash-es@3.10.1/",
"lodash@4/": "https://unpkg.com/lodash-es@4.17.21/"
}
}
</script>
Либо, можно предоставлять разные версии пакета для разных скриптов на основе path скрипта
<script type="importmap">
{
"imports": {
"lodash/": "https://unpkg.com/lodash-es@4.17.21/"
},
"scopes": {
"/static/js": {
"lodash/": "https://unpkg.com/lodash-es@3.10.1/"
}
}
}
</script>
Кроме того, можно формировать Import Map динамически
<script>
const importMap = {
imports: {
lazyload: 'IntersectionObserver' in window
? './lazyload.js'
: './lazyload-fallback.js',
},
};
const im = document.createElement('script');
im.type = 'importmap';
im.textContent = JSON.stringify(importMap);
document.currentScript.after(im);
</script>